package com.qqt.csr.order.service.statemachine.action.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.qqt.csr.common.acl.aics.AICustomerServiceClient;
import com.qqt.csr.common.acl.aics.resp.ChannelInfoDTO;
import com.qqt.csr.common.acl.aics.resp.CsMemberInfoDTO;
import com.qqt.csr.common.utils.GzipUtil;
import com.qqt.csr.message.event.intrasite.workorder.WorkOrderEventSource;
import com.qqt.csr.order.entity.WorkOrder;
import com.qqt.csr.order.enums.WorkOrderEventEnum;
import com.qqt.csr.order.enums.WorkOrderStatusEnum;
import com.qqt.csr.order.enums.WorkOrderTemplateType;
import com.qqt.csr.order.service.event.DynamicEvent;
import com.qqt.csr.order.service.event.DynamicEventSource;
import com.qqt.csr.order.service.statemachine.action.IActionPostProcessor;
import com.qqt.csr.order.service.statemachine.action.IActionPreProcessor;
import com.qqt.csr.order.service.statemachine.context.WorkOrderContext;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Component
public class EditedWorkOrderProcessor extends AbstractWorkOrderProcessor implements IActionPreProcessor, IActionPostProcessor {
    @Autowired
    private AICustomerServiceClient customerServiceClient;

    @Override
    public boolean matches(WorkOrderEventEnum event) {
        return WorkOrderEventEnum.EDITED.equals(event) || WorkOrderEventEnum.EDIT_ALLOCATED.equals(event);
    }

    @Override
    public void preProcess(WorkOrderStatusEnum from, WorkOrderStatusEnum to, WorkOrderEventEnum event, WorkOrderContext context) {
        WorkOrder toOrder = context.getToOrder();
        WorkOrder fromOrder = context.getFromOrder();

        JSONObject ext = new JSONObject();
        compareField(fromOrder.getDesigneeId(), toOrder.getDesigneeId(), "designeeId", ext);
        compareField(fromOrder.getSysNotifyFlag(), toOrder.getSysNotifyFlag(), "sysNotifyFlag", ext);
        compareField(fromOrder.getTimeoutConfig(), toOrder.getTimeoutConfig(), "timeoutConfig", ext);
        compareField(fromOrder.getPriority(), toOrder.getPriority(), "priority", ext);
        compareField(fromOrder.getConversationId(), toOrder.getConversationId(), "conversationId", ext);
        compareField(GzipUtil.compress(fromOrder.getContent()), GzipUtil.compress(toOrder.getContent()), "content", ext);
        // compareField(fromOrder.getTitle(), toOrder.getTitle(),"Title",ext);
        compareField(fromOrder.getChannelId(), toOrder.getChannelId(), "channelId", ext);
        compareField(fromOrder.getVisitorId(), toOrder.getVisitorId(), "visitorId", ext);
        compareField(fromOrder.getConversationType(), toOrder.getConversationType(), "conversationType", ext);
        compareField(fromOrder.getTimeoutFlag(), toOrder.getTimeoutFlag(), "timeoutFlag", ext);

        if (!ext.isEmpty()) {
            context.setEventExt(ext);
        }
    }

    @Override
    public void postProcess(WorkOrderStatusEnum from, WorkOrderStatusEnum to, WorkOrderEventEnum event, WorkOrderContext context) {
        if (context.getFromOrder().isNeedSysNotify()) {
            sendMsgNotify(context);
        }

        recordDynamic(context, event);
    }

    private void compareField(Long oldValue, Long newValue, String fieldName, JSONObject ext) {
        if (!NumberUtil.equals(oldValue, newValue)) {
            JSONObject value = new JSONObject();
            value.put("o", oldValue);
            value.put("n", newValue);
            ext.put(fieldName, value);
        }

    }

    private void compareField(Integer oldValue, Integer newValue, String fieldName, JSONObject ext) {
        if (!NumberUtil.equals(oldValue, newValue)) {
            JSONObject value = new JSONObject();
            value.put("o", oldValue);
            value.put("n", newValue);
            ext.put(fieldName, value);
        }
    }

    private void compareField(String oldValue, String newValue, String fieldName, JSONObject ext) {
        if (!StringUtils.equals(oldValue, newValue)) {
            JSONObject value = new JSONObject();
            value.put("o", oldValue);
            value.put("n", newValue);
            ext.put(fieldName, value);
        }
    }

    /**
     * 推送系统通知
     *
     * @param context
     */
    private void sendMsgNotify(WorkOrderContext context) {
        sendChangedOrderStatusMsgNotify(context, WorkOrderTemplateType.EDITED_WORK_ORDER, null);
        getUpdateDesigneeMsgNotify(context).forEach(msgNotify -> {
            messageEventPublisher.publishEvent(msgNotify);
        });
    }

    /**
     * 推送处理人变更系统通知
     * 需要通知的人：
     * A创建，A处理人->A变更为B处理人，通知：B（通知新处理人）
     * A创建，B处理人->A变更为C处理人，通知：B（通知原处理人）、C（通知新处理人）
     * A创建，B处理人->B变更为C处理人，通知：A（通知创建人）、C（通知新处理人）
     * A创建，B处理人->B变更A处理人，通知：A（通知新处理人、通知创建人）
     *
     * @param context
     * @return
     */
    private List<WorkOrderEventSource> getUpdateDesigneeMsgNotify(WorkOrderContext context) {
        WorkOrder toOrder = context.getToOrder();
        WorkOrder fromOrder = context.getFromOrder();
        if (!WorkOrderStatusEnum.TO_PROCESS.getStatus().equals(toOrder.getStatus())) {
            return Lists.newArrayList();
        }
        if (!fromOrder.isNeedSysNotify() || toOrder.getDesigneeId().equals(fromOrder.getDesigneeId())) {
            return Lists.newArrayList();
        }

        List<WorkOrderEventSource> msgNotifyList = new ArrayList<>();
        if (!toOrder.getDesigneeId().equals(context.getOperatorId())) {
            // 通知新处理人
            msgNotifyList.add(new WorkOrderEventSource()
                    .setWorkOrderId(fromOrder.getId())
                    .setWorkOrderName(fromOrder.getTitle())
                    .setEventType(WorkOrderTemplateType.SET_UP_PROCESSOR)
                    .setParams(new String[]{context.getOperatorName()})
                    .setLinkUrl(StringUtils.EMPTY)
                    .setExt("{\"permission\":\""+ORDER_PROCESSOR_PERM+"\"}")
                    .setRecipientIds(Lists.newArrayList(toOrder.getDesigneeId())));
        }

        if (!fromOrder.getCreatorId().equals(context.getOperatorId())) {
            // 通知创建人
            msgNotifyList.add(new WorkOrderEventSource()
                    .setWorkOrderId(fromOrder.getId())
                    .setWorkOrderName(fromOrder.getTitle())
                    .setEventType(WorkOrderTemplateType.CHANGE_PROCESSOR_PERMISSION)
                    .setParams(new String[]{context.getOperatorName()})
                    .setLinkUrl(StringUtils.EMPTY)
                    .setExt("{\"permission\":\""+ORDER_CREATOR_PERM+"\"}")
                    .setRecipientIds(Lists.newArrayList(fromOrder.getCreatorId())));
        }

        if (context.getOperatorId().equals(fromOrder.getCreatorId())
                && fromOrder.isAllocated()
                && !fromOrder.getCreatorId().equals(fromOrder.getDesigneeId())) {
            // 通知原处理人
            msgNotifyList.add(new WorkOrderEventSource()
                    .setWorkOrderId(fromOrder.getId())
                    .setWorkOrderName(fromOrder.getTitle())
                    .setEventType(WorkOrderTemplateType.CHANGE_PROCESSOR_PERMISSION)
                    .setParams(new String[]{context.getOperatorName()})
                    .setLinkUrl(StringUtils.EMPTY)
                    .setExt("{\"permission\":\""+ORDER_POOL_PERM+"\"}")
                    .setRecipientIds(Lists.newArrayList(fromOrder.getDesigneeId())));
        }

        return msgNotifyList;
    }

    /**
     * 记录动态
     *
     * @param context
     */
    private void recordDynamic(WorkOrderContext context, WorkOrderEventEnum event) {
        if (MapUtils.isEmpty(context.getEventExt())) {
            return;
        }

        List<DynamicEventSource.ChangeField> changeFields = new ArrayList<>();

        if (context.getEventExt().containsKey("designeeId")) {
            Long nDesigneeId = Optional.ofNullable(context.getToOrder().getDesigneeId()).orElse(0L);
            String nDesigneeName = customerServiceClient.getNormalListBy(Lists.newArrayList(nDesigneeId)).stream().map(CsMemberInfoDTO::getNickName).findFirst().orElse(StringUtils.EMPTY);
            changeFields.add(DynamicEventSource.ChangeField.builder().field("处理人").newValue(nDesigneeName).oldValue(StringUtils.EMPTY).build());
        }

        if (context.getEventExt().containsKey("timeoutFlag")) {
            String nValue = context.getToOrder().getTimeoutFlag() == 1 ? "设置" : "不设置";
            String oValue = context.getFromOrder().getTimeoutFlag() == 1 ? "设置" : "不设置";
            changeFields.add(DynamicEventSource.ChangeField.builder().field("工单超时").newValue(nValue).oldValue(oValue).build());
        }

        if (context.getEventExt().containsKey("timeoutConfig")) {
            Long nValue = context.getToOrder().getTimeoutConfig() / 3600L;
            Long oValue = context.getFromOrder().getTimeoutConfig() / 3600L;
            changeFields.add(DynamicEventSource.ChangeField.builder().field("工单超时配置").newValue(nValue + "小时").oldValue(oValue + "小时").build());
        }

        if (context.getEventExt().containsKey("priority")) {
            String nValue = context.getToOrder().getPriority() == 0 ? "低" : context.getToOrder().getPriority() == 1 ? "一般" : "紧急";
            String oValue = context.getFromOrder().getPriority() == 0 ? "低" : context.getFromOrder().getPriority() == 1 ? "一般" : "紧急";
            changeFields.add(DynamicEventSource.ChangeField.builder().field("优先级").newValue(nValue).oldValue(oValue).build());
        }

        if (context.getEventExt().containsKey("channelId")) {
            ChannelInfoDTO nChannelInfoDTO = customerServiceClient.queryChannelInfo(context.getToOrder().getChannelId());
            String nValue = Optional.ofNullable(nChannelInfoDTO).map(ChannelInfoDTO::getName).orElse(StringUtils.EMPTY);
            changeFields.add(DynamicEventSource.ChangeField.builder().field("关联渠道").newValue(nValue).oldValue(StringUtils.EMPTY).build());
        }

        if (context.getEventExt().containsKey("conversationType")) {
            String nValue = context.getToOrder().getConversationType() == 0 ? "不关联" : context.getToOrder().getConversationType() == 1 ? "机器人" : "人工";
            String oValue = context.getFromOrder().getConversationType() == 0 ? "不关联" : context.getFromOrder().getConversationType() == 1 ? "机器人" : "人工";
            changeFields.add(DynamicEventSource.ChangeField.builder().field("关联会话类型").newValue(nValue).oldValue(oValue).build());
        }

        if (context.getEventExt().containsKey("conversationId")) {
            String nValue = context.getToOrder().getConversationId();
            String oValue = context.getFromOrder().getConversationId();
            changeFields.add(DynamicEventSource.ChangeField.builder().field("关联会话").newValue(nValue).oldValue(oValue).build());
        }

        if (context.getEventExt().containsKey("content")) {
            changeFields.add(DynamicEventSource.ChangeField.builder().field("工单内容").newValue(StringUtils.EMPTY).oldValue(StringUtils.EMPTY).build());
        }

        if (context.getEventExt().containsKey("visitorId")) {
            String nValue = context.getToOrder().getVisitorId();
            String oValue = context.getFromOrder().getVisitorId();
            changeFields.add(DynamicEventSource.ChangeField.builder().field("访客ID").newValue(nValue).oldValue(oValue).build());
        }

        DynamicEventSource eventSource = new DynamicEventSource()
                .setEvent(event)
                .setOrderId(context.getToOrder().getId())
                .setChangeFields(changeFields);
        dynamicEventListener.onApplicationEvent(new DynamicEvent(eventSource));
    }


}
